home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 16 / CU Amiga Magazine's Super CD-ROM 16 (1997-10-16)(EMAP Images)(GB)[!][issue 1997-11].iso / CUCD / Graphics / Ghostscript / source / gsht1.c < prev    next >
C/C++ Source or Header  |  1997-05-12  |  10KB  |  357 lines

  1. /* Copyright (C) 1994, 1995, 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* gsht1.c */
  20. /* Extended halftone operators for Ghostscript library */
  21. #include "memory_.h"
  22. #include "gx.h"
  23. #include "gserrors.h"
  24. #include "gsstruct.h"
  25. #include "gsutil.h"            /* for gs_next_ids */
  26. #include "gzstate.h"
  27. #include "gxdevice.h"            /* for gzht.h */
  28. #include "gzht.h"
  29.  
  30. /* Define the size of the halftone tile cache. */
  31. #define max_tile_bytes_LARGE 4096
  32. #define max_tile_bytes_SMALL 512
  33. #if arch_small_memory
  34. #  define max_tile_cache_bytes max_tile_bytes_SMALL
  35. #else
  36. #  define max_tile_cache_bytes\
  37.      (gs_if_debug_c('.') ? max_tile_bytes_SMALL : max_tile_bytes_LARGE)
  38. #endif
  39.  
  40. /* Imports from gscolor.c */
  41. void load_transfer_map(P3(gs_state *, gx_transfer_map *, floatp));
  42.  
  43. /* Forward declarations */
  44. private int process_spot(P4(gx_ht_order *, gs_state *,
  45.   gs_spot_halftone *, gs_memory_t *));
  46. private int process_threshold(P4(gx_ht_order *, gs_state *,
  47.   gs_threshold_halftone *, gs_memory_t *));
  48.  
  49. /* Structure types */
  50. public_st_halftone_component();
  51. public_st_ht_component_element();
  52.  
  53. /* GC procedures */
  54.  
  55. #define hptr ((gs_halftone_component *)vptr)
  56.  
  57. private ENUM_PTRS_BEGIN(halftone_component_enum_ptrs) return 0;
  58.     case 0:
  59.         if ( hptr->type != ht_type_threshold )
  60.           return 0;
  61.         ENUM_RETURN_CONST_STRING_PTR(gs_halftone_component, params.threshold.thresholds);
  62. ENUM_PTRS_END
  63.  
  64. private RELOC_PTRS_BEGIN(halftone_component_reloc_ptrs) {
  65.     if ( hptr->type == ht_type_threshold )
  66.       RELOC_CONST_STRING_PTR(gs_halftone_component, params.threshold.thresholds);
  67. } RELOC_PTRS_END
  68.  
  69. #undef hptr
  70.  
  71. /* setcolorscreen */
  72. int
  73. gs_setcolorscreen(gs_state *pgs, gs_colorscreen_halftone *pht)
  74. {    gs_halftone ht;
  75.  
  76.     ht.type = ht_type_colorscreen;
  77.     ht.params.colorscreen = *pht;
  78.     return gs_sethalftone(pgs, &ht);
  79. }
  80.  
  81. /* currentcolorscreen */
  82. int
  83. gs_currentcolorscreen(gs_state *pgs, gs_colorscreen_halftone *pht)
  84. {    int code;
  85.     switch ( pgs->halftone->type )
  86.     {
  87.     case ht_type_colorscreen:
  88.         *pht = pgs->halftone->params.colorscreen;
  89.         return 0;
  90.     default:
  91.         code = gs_currentscreen(pgs, &pht->screens.colored.gray);
  92.         if ( code < 0 )
  93.             return code;
  94.         pht->screens.colored.red = pht->screens.colored.gray;
  95.         pht->screens.colored.green = pht->screens.colored.gray;
  96.         pht->screens.colored.blue = pht->screens.colored.gray;
  97.         return 0;
  98.     }
  99. }
  100.  
  101. /* Set the halftone in the graphics state. */
  102. int
  103. gs_sethalftone(gs_state *pgs, gs_halftone *pht)
  104. {    gs_halftone ht;
  105.  
  106.     ht = *pht;
  107.     ht.rc.memory = pgs->memory;
  108.     return gs_sethalftone_allocated(pgs, &ht);
  109. }
  110. int
  111. gs_sethalftone_allocated(gs_state *pgs, gs_halftone *pht)
  112. {    gx_device_halftone dev_ht;
  113.     int code = gs_sethalftone_prepare(pgs, pht, &dev_ht);
  114.  
  115.     if ( code < 0 )
  116.       return code;
  117.     dev_ht.rc.memory = pht->rc.memory;
  118.     return gx_ht_install(pgs, pht, &dev_ht);
  119. }
  120. /* Prepare the halftone, but don't install it. */
  121. int
  122. gs_sethalftone_prepare(gs_state *pgs, gs_halftone *pht,
  123.   gx_device_halftone *pdht)
  124. {    gs_memory_t *mem = pht->rc.memory;
  125.     gx_ht_order_component *pocs = 0;
  126.     int code = 0;
  127.  
  128.     switch ( pht->type )
  129.     {
  130.     case ht_type_colorscreen:
  131.     {    gs_screen_halftone *phc =
  132.             pht->params.colorscreen.screens.indexed;
  133.         static const gs_ht_separation_name cnames[4] =
  134.         { gs_ht_separation_Default, gs_ht_separation_Red,
  135.           gs_ht_separation_Green, gs_ht_separation_Blue
  136.         };
  137.         static const int cindex[4] = { 3, 0, 1, 2 };
  138.         int i;
  139.         pocs = gs_alloc_struct_array(mem, 4,
  140.                          gx_ht_order_component,
  141.                          &st_ht_order_component_element,
  142.                          "gs_sethalftone");
  143.         if ( pocs == 0 )
  144.             return_error(gs_error_VMerror);
  145.         for ( i = 0; i < 4; i++ )
  146.         {    gs_screen_enum senum;
  147.             int ci = cindex[i];
  148.             gx_ht_order_component *poc = &pocs[i];
  149.  
  150.             code = gx_ht_process_screen_memory(&senum, pgs,
  151.                 &phc[ci], gs_currentaccuratescreens(), mem);
  152.             if ( code < 0 )
  153.                 break;
  154. #define sorder senum.order
  155.             poc->corder = sorder;
  156.             poc->cname = cnames[i];
  157.             if ( i == 0 )        /* Gray = Default */
  158.                 pdht->order = sorder;
  159.             else
  160.             {    uint tile_bytes =
  161.                   sorder.raster *
  162.                     (sorder.num_bits / sorder.width);
  163.                 uint num_tiles =
  164.                   max_tile_cache_bytes / tile_bytes + 1;
  165.                 gx_ht_cache *pcache =
  166.                   gx_ht_alloc_cache(mem, num_tiles,
  167.                             tile_bytes * num_tiles);
  168.                 if ( pcache == 0 )
  169.                   {    code = gs_note_error(gs_error_VMerror);
  170.                     break;
  171.                   }
  172.                 poc->corder.cache = pcache;
  173.                 gx_ht_init_cache(pcache, &poc->corder);
  174.             }
  175. #undef sorder
  176.         }
  177.         if ( code < 0 )
  178.           break;
  179.         pdht->components = pocs;
  180.         pdht->num_comp = 4;
  181.     }    break;
  182.     case ht_type_spot:
  183.         code = process_spot(&pdht->order, pgs, &pht->params.spot, mem);
  184.         if ( code < 0 )
  185.             return code;
  186.         pdht->components = 0;
  187.         break;
  188.     case ht_type_threshold:
  189.         code = process_threshold(&pdht->order, pgs,
  190.                      &pht->params.threshold, mem);
  191.         if ( code < 0 )
  192.             return code;
  193.         pdht->components = 0;
  194.         break;
  195.     case ht_type_multiple:
  196.     case ht_type_multiple_colorscreen:
  197.     {    uint count = pht->params.multiple.num_comp;
  198.         bool have_Default = false;
  199.         uint i;
  200.         gs_halftone_component *phc = pht->params.multiple.components;
  201.         gx_ht_order_component *poc_next;
  202.         pocs = gs_alloc_struct_array(mem, count,
  203.                          gx_ht_order_component,
  204.                          &st_ht_order_component_element,
  205.                          "gs_sethalftone");
  206.         if ( pocs == 0 )
  207.             return_error(gs_error_VMerror);
  208.         poc_next = pocs + 1;
  209.         for ( i = 0; i < count; i++, phc++ )
  210.         {    gx_ht_order_component *poc;
  211.             if ( phc->cname == gs_ht_separation_Default )
  212.             {    if ( have_Default )
  213.                 {    /* Duplicate Default */
  214.                     code = gs_note_error(gs_error_rangecheck);
  215.                     break;
  216.                 }
  217.                 poc = pocs;
  218.                 have_Default = true;
  219.             }
  220.             else if ( i == count - 1 && !have_Default )
  221.             {    /* No Default */
  222.                 code = gs_note_error(gs_error_rangecheck);
  223.                 break;
  224.             }
  225.             else
  226.                 poc = poc_next++;
  227.             poc->cname = phc->cname;
  228.             switch ( phc->type )
  229.             {
  230.             case ht_type_spot:
  231.                 code = process_spot(&poc->corder, pgs,
  232.                             &phc->params.spot, mem);
  233.                 break;
  234.             case ht_type_threshold:
  235.                 code = process_threshold(&poc->corder, pgs,
  236.                         &phc->params.threshold, mem);
  237.                 break;
  238.             default:
  239.                 code = gs_note_error(gs_error_rangecheck);
  240.                 break;
  241.             }
  242.             if ( code < 0 )
  243.               break;
  244.             if ( poc != pocs )
  245.             {    gx_ht_cache *pcache =
  246.                   gx_ht_alloc_cache(mem, 1,
  247.                             poc->corder.raster *
  248.                             (poc->corder.num_bits /
  249.                              poc->corder.width));
  250.                 if ( pcache == 0 )
  251.                   {    code = gs_note_error(gs_error_VMerror);
  252.                     break;
  253.                   }
  254.                 poc->corder.cache = pcache;
  255.                 gx_ht_init_cache(pcache, &poc->corder);
  256.             }
  257.         }
  258.         if ( code < 0 )
  259.           break;
  260.         pdht->order = pocs[0].corder;        /* Default */
  261.         if ( count == 1 )
  262.         {    /* We have only a Default; */
  263.             /* we don't need components. */
  264.             gs_free_object(mem, pocs, "gs_sethalftone");
  265.             pdht->components = 0;
  266.         }
  267.         else
  268.         {    pdht->components = pocs;
  269.             pdht->num_comp = count;
  270.         }
  271.     }    break;
  272.     default:
  273.         return_error(gs_error_rangecheck);
  274.     }
  275.     if ( code < 0 )
  276.       gs_free_object(mem, pocs, "gs_sethalftone");
  277.     return code;
  278. }
  279.  
  280. /* ------ Internal routines ------ */
  281.  
  282. /* Process a transfer function override, if any. */
  283. private int
  284. process_transfer(gx_ht_order *porder, gs_state *pgs,
  285.   gs_mapping_proc tproc, gs_memory_t *mem)
  286. {    gx_transfer_map *pmap;
  287.  
  288.     if ( tproc == 0 )
  289.       return 0;
  290.     pmap = gs_alloc_struct(mem, gx_transfer_map, &st_transfer_map,
  291.                    "process_transfer");
  292.     if ( pmap == 0 )
  293.       return_error(gs_error_VMerror);
  294.     pmap->proc = tproc;
  295.     pmap->id = gs_next_ids(1);
  296.     load_transfer_map(pgs, pmap, 0.0);
  297.     porder->transfer = pmap;
  298.     return 0;
  299. }
  300.  
  301. /* Process a spot plane. */
  302. private int
  303. process_spot(gx_ht_order *porder, gs_state *pgs,
  304.   gs_spot_halftone *phsp, gs_memory_t *mem)
  305. {    gs_screen_enum senum;
  306.  
  307.     int code = gx_ht_process_screen_memory(&senum, pgs, &phsp->screen,
  308.                     phsp->accurate_screens, mem);
  309.     if ( code < 0 )
  310.         return code;
  311.     *porder = senum.order;
  312.     return process_transfer(porder, pgs, phsp->transfer, mem);
  313. }
  314.  
  315. /* Process a threshold plane. */
  316. private int
  317. process_threshold(gx_ht_order *porder, gs_state *pgs,
  318.   gs_threshold_halftone *phtp, gs_memory_t *mem)
  319. {    int code;
  320.  
  321.     porder->params.M = phtp->width, porder->params.N = 0;
  322.     porder->params.R = 1;
  323.     porder->params.M1 = phtp->height, porder->params.N1 = 0;
  324.     porder->params.R1 = 1;
  325.     code = gx_ht_alloc_order(porder, phtp->width, phtp->height,
  326.                  0, 256, mem);
  327.     if ( code < 0 )
  328.       return code;
  329.     gx_ht_construct_threshold_order(porder, phtp->thresholds.data);
  330.     return process_transfer(porder, pgs, phtp->transfer, mem);
  331. }
  332.  
  333. /* Construct the halftone order from a threshold array. */
  334. void
  335. gx_ht_construct_threshold_order(gx_ht_order *porder, const byte *thresholds)
  336. {    uint size = porder->num_bits;
  337.     uint *levels = porder->levels;
  338.     gx_ht_bit *bits = porder->bits;
  339.     uint i, j;
  340.     for ( i = 0; i < size; i++ )
  341.         bits[i].mask = max(1, thresholds[i]);
  342.     gx_sort_ht_order(bits, size);
  343.     /* We want to set levels[j] to the lowest value of i */
  344.     /* such that bits[i].mask > j. */
  345.     for ( i = 0, j = 0; i < size; i++ )
  346.     {    if ( bits[i].mask != j )
  347.         {    if_debug3('h', "[h]levels[%u..%u] = %u\n",
  348.                   j, (uint)bits[i].mask, i);
  349.             while ( j < bits[i].mask )
  350.                 levels[j++] = i;
  351.         }
  352.     }
  353.     while ( j < 256 )
  354.         levels[j++] = size;
  355.     gx_ht_construct_bits(porder);
  356. }
  357.